<template>
  <div ref="pageDesigner" class="page-designer" :style="designerStyle" @click="handleClick">
    <div ref="horizontalRuler" class="ruler horizontal-ruler"></div>
    <div ref="verticalRuler" class="ruler vertical-ruler"></div>
    <div class="page-widget-cantainer">
      <div ref="widgetCanvasRef" class="page-widget widget-canvas" :style="canvasStyle" @click="canvasClickHandler"
        @dragover="onDragOver" @drop="onDrop" @contextmenu.stop="onContextMenu">
        <template v-for="(widget, index) in designer.widgetList" :key="widget.id">
          <component :is="getWidgetName(widget)" :ref="widget.id" :field="widget" :designer="designer"
            :settings="settings" :parent-list="designer.widgetList" :index-of-parent-list="index" :parent-widget="null"
            :design-state="true" :scale="scale" :style="{
              left: widget.options.x * scale + 'px',
              top: widget.options.y * scale + 'px'
            }" />
        </template>
      </div>
    </div>
    <el-popover popper-class="context-menu-popover" :width="80" :popper-style="{
      left: contextMenuPosition.x - 10 + 'px',
      top: contextMenuPosition.y + 10 + 'px'
    }" :visible="contextMenuVisible">
      <template #reference>
        <span style="display: none"></span>
      </template>
      <ul class="context-menu-list">
        <li v-if="contextMenuCopy" class="context-menu-item" @click="copyWidget">复制</li>
        <li v-if="contextMenuPaste" class="context-menu-item" @click="pasteWidget">粘贴</li>
        <li v-if="contextMenuDelete" class="context-menu-item" @click="deleteWidget">删除</li>
        <li v-if="contextMenuEdit" class="context-menu-item" @click="editWidget">编辑</li>
      </ul>
    </el-popover>
  </div>
</template>

<script>
import { useMouseInElement } from '@vueuse/core'
import { ref } from 'vue'
import Ruler from '@scena/ruler'
import * as CONST from '../const'
import { GET_IMAGE_RESOURCE, GET_IMAGE_RESOURCE_RESULT } from '@/designer/event'
import { deepClone, generateId } from '@/utils/util'

export default {
  name: 'VFormWidget',
  componentName: 'VFormWidget',
  provide() {
    return {
      refList: this.widgetRefList,
      getOptionData: () => this.optionData,
      globalModel: {
        formModel: this.formModel
      }
    }
  },
  inject: ['getDesignerConfig'],
  props: {
    designer: Object,
    settings: Object,
    optionData: {
      //prop传入的选项数据
      type: Object,
      default: () => ({})
    }
  },
  setup() {
    const widgetCanvasRef = ref(null)
    const { elementX, elementY, elementWidth, elementHeight } = useMouseInElement(widgetCanvasRef)
    const contextMenuActions = {
  copy: (designer, isModule) => {
    if (isModule) {
      // 调用Module组件的复制方法
      designer.formWidget.$refs.moduleEditRef?.copyWidget?.();
      //console.log('调用Module组件的复制方法')
    } else {
      designer.copySelectedWidget(designer.selectedWidget);
    }
  },
  paste: (designer, isModule, position) => {
    if (isModule) {
      // 调用Module组件的粘贴方法
      designer.formWidget.$refs.moduleEditRef?.pasteWidget?.();
      console.log('111111111111111111')
    } else {
      designer.pasteWidget(position, designer.formWidget.scale);
      console.log('2222222222222222222')
    }
  }
};
    return {
      widgetCanvasRef,
      elementX,
      elementY,
      elementWidth,
      elementHeight
    }
    
  },
  data() {
    return {
       contextMenuVisible: false,
    contextMenuPosition: { x: 0, y: 0 },
    contextMenuContext: null,
    contextMenuIsModule: false,
    contextMenuCopy: false,
    contextMenuPaste: false,
    contextMenuDelete: false,
    contextMenuEdit: false,
      imageUrl: '',
      formModel: {},
      widgetRefList: {},
      vRuler: null,
      hRuler: null,
      contextMenuVisible: false,
      contextMenuPosition: { x: 0, y: 0 }
    }
  },
  computed: {
    scale() {
      return this.settings && this.settings.scale ? this.settings.scale / 100 : 1
    },
    canvasWidth() {
      if (this.settings) {
        if (this.settings.screenOrientation === 0 || this.settings.screenOrientation === 2) {
          return this.settings.width
        } else {
          return this.settings.height
        }
      }
      return 1024
    },
    canvasHeight() {
      if (this.settings) {
        if (this.settings.screenOrientation === 1 || this.settings.screenOrientation === 3) {
          return this.settings.width
        } else {
          return this.settings.height
        }
      }
      return 600
    },
    scaleCanvasWidth() {
      return this.canvasWidth * this.scale
    },
    scaleCanvasHeight() {
      return this.canvasHeight * this.scale
    },
    designerStyle() {
      return {
        width: this.scaleCanvasWidth + 60 + 'px',
        height: this.scaleCanvasHeight + 60 + 'px'
      }
    },
    canvasStyle() {
      let backgroundColor = '#FFFFFF'
      if (this.designer) {
        backgroundColor = this.designer.options.rgb
      }
      let backgroundImage = ''
      if (this.designer && this.designer.options.bgType === CONST.PAGE_BG_TYPE.IMG) {
        backgroundImage = this.imageUrl
      }

      return {
        width: this.scaleCanvasWidth + 'px',
        height: this.scaleCanvasHeight + 'px',
        backgroundColor,
        backgroundImage,
        backgroundPositionX: 'center',
        backgroundPositionY: 'center',
        backgroundRepeat: 'no-repeat'
      }
    },
    contextMenuCopy() {
      return this.designer && this.designer.selectedWidget
    },
    contextMenuPaste() {
      if (!this.designer) {
        return false
      }

      if (!this.designer.copyWidget) {
        return false
      }

      return true
    },
    contextMenuDelete() {
      return this.designer && this.designer.selectedWidget
    },
    contextMenuEdit() {
      return (
        this.designer &&
        this.designer.selectedWidget &&
        (this.designer.selectedWidget.type === 'button' ||
          this.designer.selectedWidget.type === 'module' ||
          this.designer.selectedWidget.type === 'slidePage')
      )
    }
  },
  watch: {
    canvasHeight(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderVerticalRuler()
        })
      }
    },
    canvasWidth(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderHorizontalRuler()
        })
      }
    },
    scale(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$nextTick(() => {
          this.reRenderHorizontalRuler()
          this.reRenderVerticalRuler()
        })
      }
    },
    'designer.options.img': {
      deep: true,
      handler(newValue, oldValue) {
        if (!newValue) {
          this.imageUrl = ''
          return
        }

        if (newValue !== oldValue) {
          //TODO
          this.$emitter.emit(GET_IMAGE_RESOURCE, newValue)
        }
      }
    }
  },
  mounted() {
    this.$emitter.on(GET_IMAGE_RESOURCE_RESULT, (data) => {
      if (data && data.name === this.designer.options.img) {
        if (data.result) {
          this.imageUrl = `url(${data.result.url})`
        } else {
          this.imageUrl = ''
        }
      }
    })

    this.$emitter.on('showContextMenu', this.showContextMenu)

    if (this.designer && this.designer.options.img) {
      this.$emitter.emit(GET_IMAGE_RESOURCE, this.designer.options.img)
    }

    this.$emitter.on('drag-end', this.handleDragEnd)

    this.designer.registerFormWidget(this)

    this.widgetCanvasRef = this.$refs.widgetCanvasRef

    this.reRenderHorizontalRuler()
    this.reRenderVerticalRuler()

    document.addEventListener('click', () => {
      this.hideContextMenu()
    })
    // 新增键盘事件监听
    //document.addEventListener('keydown', this.handleKeyDown)
  },
  unmounted() {
    this.$emitter.off('drag-end', this.handleDragEnd)
    // 新增：移除键盘事件监听
    //document.removeEventListener('keydown', this.handleKeyDown)
  },
  methods: {
    // 新增方法：处理键盘快捷键
    // handleKeyDown(event) {
    //   // 检查是否在代码编辑区（如textarea或contenteditable元素）
    //   const activeElement = document.activeElement;
    //   const isInCodeEditor = activeElement.tagName === 'TEXTAREA' ||
    //     activeElement.tagName === 'INPUT' ||
    //     activeElement.isContentEditable;

    //   if (isInCodeEditor) {
    //     return; // 如果在代码编辑区，不处理快捷键
    //   }

    //   // 检查是否按下了 Ctrl 键
    //   if (event.ctrlKey || event.metaKey) {
    //     switch (event.key.toLowerCase()) {
    //       case 'c':
    //         // 阻止默认行为
    //         event.preventDefault();
    //         this.copyWidget();
    //         break;
    //       case 'v':
    //         // 阻止默认行为
    //         event.preventDefault();
    //         this.pasteWidget();
    //         break;
    //     }
    //   }
    // },
    reRenderHorizontalRuler() {
      if (this.hRuler) {
        this.$refs.horizontalRuler.removeChild(this.$refs.horizontalRuler.querySelector('canvas'))
        this.hRuler = null
      }

      this.hRuler = new Ruler(this.$refs.horizontalRuler, {
        type: 'horizontal',
        width: this.scaleCanvasWidth + 30,
        height: 30,
        zoom: this.scale,
        backgroundColor: '#daeaff',
        lineColor: '#000000',
        textColor: '#154a93',
        textAlign: 'right'
      })
    },
    reRenderVerticalRuler() {
      if (this.vRuler) {
        this.$refs.verticalRuler.removeChild(this.$refs.verticalRuler.querySelector('canvas'))
        this.vRuler = null
      }

      this.vRuler = new Ruler(this.$refs.verticalRuler, {
        type: 'vertical',
        width: 30,
        height: this.scaleCanvasHeight + 30,
        zoom: this.scale,
        backgroundColor: '#daeaff',
        lineColor: '#000000',
        textColor: '#154a93',
        lineWidth: 1
      })
    },
    getWidgetName(widget) {
      return widget.type + '-widget'
    },
    canvasClickHandler() {
      // console.log('canvasClickHandler...')
      this.designer.setSelected(null)
      this.hideContextMenu()
    },

    handleDragEnd(widget) {
      // console.log('handleDragEnd...')
      if (this.designer.hasWidget(widget, this.designer.widgetList)) {
        this.updateWidgetPosition(widget)

        if (this.$refs[widget.id] && this.$refs[widget.id].length > 0) {
          const widgetInstance = this.$refs[widget.id][0]
          widgetInstance.$el.style.transform = `translate(0, 0)`
        }

        // 清除拖拽元素
        this.designer.drag(null)
        // 保存操作历史
        this.designer.emitHistoryChange()
      }
    },

    onDragOver(evt) {
      // console.log('onDragOver...')
      evt.preventDefault()

      const widget = this.designer.dragWidget
      if (this.$refs[widget.id] && this.$refs[widget.id].length > 0) { //不是复制，在区域内拖动时候触发
        // console.log(123)
        const translateX = this.elementX - widget.options.x * this.scale - widget.offset.x
        const translateY = this.elementY - widget.options.y * this.scale - widget.offset.y

        const widgetInstance = this.$refs[widget.id][0]
        widgetInstance.$el.style.transform = `translate(${translateX}px, ${translateY}px)`
      }
    },

    onDrop(evt) {
      // console.log('onDrop...')
      evt.preventDefault()

      if (evt.dataTransfer.effectAllowed === 'copy') {
        const widget = this.designer.dragWidget
        this.designer.addDragWidget(widget)

        this.updateWidgetPosition(widget)

        // 清除拖拽元素
        this.designer.drag(null)

        // 保存操作历史
        this.designer.emitHistoryChange()
      }
    },

    updateWidgetPosition(widget) {
  if (!widget) return;

  this.$nextTick(() => {
    if (widget.offset) {
      // 获取容器尺寸
      const containerWidth = this.canvasWidth;
      const containerHeight = this.canvasHeight;
      
      // 获取组件尺寸（带默认值）
      const widgetWidth = widget.options.width || 100;
      const widgetHeight = widget.options.height || 100;

      // 计算边界安全的位置
      let newX = this.elementX - widget.offset.x;
      let newY = this.elementY - widget.offset.y;

      // 确保组件不超出容器边界
      newX = Math.max(0, Math.min(newX, containerWidth - widgetWidth));
      newY = Math.max(0, Math.min(newY, containerHeight - widgetHeight));

      // 应用四舍五入后的位置
      widget.options.x = Math.round(newX);
      widget.options.y = Math.round(newY);
      
      // 如果组件过大则自动调整
      if (widgetWidth > containerWidth) {
        widget.options.width = containerWidth;
        this.$message.warning('组件宽度已调整以适应容器');
      }
      if (widgetHeight > containerHeight) {
        widget.options.height = containerHeight;
        this.$message.warning('组件高度已调整以适应容器');
      }

      delete widget.offset;
    }
  });
},
    onContextMenu(event) {
  event.preventDefault()
  event.stopPropagation()
  
  // 获取点击位置下的组件
  const clickedElement = document.elementFromPoint(event.clientX, event.clientY)
  const widgetElement = clickedElement.closest('.widget-item') // 假设组件有 widget-item 类
  
  if (widgetElement) {
    const widgetId = widgetElement.dataset.widgetId
    const widget = this.findWidgetById(widgetId)
    if (widget) {
      this.designer.setSelected(widget)
    }
  } else {
    this.designer.setSelected(null)
  }
  
  this.showContextMenu({
    clientX: event.clientX,
    clientY: event.clientY,
    designerId: this.designer.id
  })
},

    showContextMenu(params) {
  // 只处理当前设计器的菜单
  if (params.designerId && params.designerId !== this.designer?.id) {
    return;
  }
  
  // 更新菜单状态
  this.contextMenuVisible = true;
  this.contextMenuPosition = { 
    x: params.clientX, 
    y: params.clientY 
  };
  this.contextMenuContext = params.context;
  this.contextMenuIsModule = params.isModule;
  
  // 根据当前状态决定显示哪些菜单项
  this.contextMenuCopy = params.hasSelection; // 有选中组件 → 显示复制
  this.contextMenuPaste = params.hasClipboard; // 有可粘贴内容 → 显示粘贴
  this.contextMenuDelete = params.hasSelection; // 有选中组件 → 显示删除
  
  // 编辑菜单只在选中特定组件时显示
  if (params.hasSelection && params.context?.selectedWidget) {
    const widgetType = params.context.selectedWidget.type;
    this.contextMenuEdit = ['button', 'module', 'slidePage'].includes(widgetType);
  } else {
    this.contextMenuEdit = false;
  }
},

    hideContextMenu() {
      this.contextMenuVisible = false
    },

    // 修改copyWidget方法
 copyWidget() {
    if (this.contextMenuIsModule && this.contextMenuContext) {
      this.contextMenuContext.copyWidget();
      console.log('调用Module组件的复制方法')
    } else if (this.designer?.selectedWidget) {
      this.designer.copySelectedWidget(this.designer.selectedWidget);
      console.log('调用主设计器的复制方法')
    }
  },

   pasteWidget() {
    if (this.contextMenuIsModule && this.contextMenuContext) {
      this.contextMenuContext.pasteWidget(this.contextMenuPosition);
      console.log('调用Module组件的粘贴方法')
    } else if (this.designer?.copyWidget) {
      this.designer.pasteWidget(this.contextMenuPosition, this.scale);
      console.log('调用主设计器的粘贴方法')
    }
  },
    deleteWidget() {
      if (!this.designer.selectedWidget) {
        this.$message.error('请选择删除的组件')
        return
      }
      this.designer.deleteWidget(this.designer.selectedWidget, this.designer.widgetList)
    },

    editWidget() {
      if (!this.designer.selectedWidget) {
        this.$message.error('请选择编辑的组件')
        return
      }

      if (
        this.designer.selectedWidget.type !== 'button' &&
        this.designer.selectedWidget.type !== 'module' &&
        this.designer.selectedWidget.type !== 'slidePage'
      ) {
        this.$message.error('该组件不支持编辑')
        return
      }

      this.designer.editWidget(this.designer.selectedWidget)
    },

    getFormData() {
      return this.formModel
    },

    getWidgetRef(widgetName, showError = false) {
      let foundRef = this.widgetRefList[widgetName]
      if (!foundRef && !!showError) {
        this.$message.error(this.i18nt('designer.hint.refNotFound') + widgetName)
      }
      return foundRef
    },

    clearWidgetRefList() {
      Object.keys(this.widgetRefList).forEach((widgetRef) => {
        delete this.widgetRefList[widgetRef]
      })
    },

    deleteWidgetRef(widgetRefName) {
      delete this.widgetRefList[widgetRefName]
    }
  }
}
</script>

<style lang="scss" scoped>
.container-scroll-bar {

  :deep(.el-scrollbar__wrap),
  :deep(.el-scrollbar__view) {
    overflow-x: hidden;
  }
}

.page-designer {
  position: relative;
  overflow: hidden;

  .ruler {
    position: absolute;
    top: 0;
    left: 0;
  }

  .ruler.horizontal-ruler {
    left: 30px;
    right: 0;
  }

  .ruler.vertical-ruler {
    top: 30px;
    bottom: 0;
  }

  .page-widget-cantainer {
    position: absolute;
    left: 30px;
    right: 30px;
    top: 30px;
    bottom: 30px;

    :deep(.el-row) {
      padding: 2px;
      border: 1px dashed rgba(170, 170, 170, 0.75);
    }
  }
}

.grid-cell {
  min-height: 30px;
  border-right: 1px dotted #cccccc;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>
